//
// Created by hshgeek on 2023/11/19.
//
#include "initializer_list"
#include "iostream"
#include "memory"
#include "string"
#include "vector"

using std::make_shared;
using std::shared_ptr;
using std::string;
using std::vector;

class StrBlob {
public:
  using size_type = vector<string>::size_type;

  StrBlob();
  StrBlob(std::initializer_list<string> il);
  size_type size() const { return data->size(); }
  bool empty() const { return data->empty(); }

  // 添加元素
  void push_back(const string &t) { data->push_back(t); }
  void pop_back();
  // 元素访问
  string &front();
  string &back();
  const string &front() const;
  const string &back() const;

private:
  shared_ptr<vector<string>> data;
  // 如果 data[i] 不合法，抛出一个异常
  void check(size_type i, const string &msg) const;
};

StrBlob::StrBlob() : data(make_shared<vector<string>>()) {}
StrBlob::StrBlob(std::initializer_list<string> il)
    : data(make_shared<vector<string>>(il)) {}
void StrBlob::check(StrBlob::size_type i, const std::string &msg) const {
  if (i >= data->size()) {
    throw std::out_of_range(msg);
  }
}

const string &StrBlob::front() const {
  check(0, "front on empty StrBlob");
  return data->front();
}

const string &StrBlob::back() const {
  check(0, "back on empty StrBlob");
  return data->back();
}

string &StrBlob::front() {
  check(0, "front on empty StrBlob");
  return data->front();
}

string &StrBlob::back() {
  check(0, "back on empty StrBlob");
  return data->back();
}

void StrBlob::pop_back() {
  check(0, "pop_back on empty StrBlob");
  data->pop_back();
}

int main() {
  StrBlob b1;
  {
    StrBlob b2 = {"a", "an", "the"};
    b1 = b2;
    b2.push_back("about");
  }
  std::cout << b1.size() << std::endl;
  std::cout << b1.front() << " " << b1.back() << std::endl;
}
